#define _GNU_SOURCE

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <string.h>
#include <unistd.h>
#include <sched.h>
#include <errno.h>

int main(int argc, char *argv[])
{
    if (argc < 5)
    {
        printf("usage: fastChangeCore 1 pid startCoreId endCoreId\n");
        printf("usage: fastChangeCore 2 pid core1 core2\n");
        printf("usage: fastChangeCore 3 pid core1 core2 ...\n");
        return 1;
    }
    cpu_set_t mask;
    int coreList[128];
    int mode = atoi(argv[1]);
    int pid = atoi(argv[2]);
    if (mode == 1)
    {
        int startCoreId = atoi(argv[3]);
        int endCoreId = atoi(argv[4]);
        int coreId = startCoreId;
        while (1)
        {
            CPU_ZERO(&mask);
            CPU_SET(coreId, &mask);
            // 进程迁移到CPU i
            if (sched_setaffinity(pid, sizeof(mask), &mask) == -1)
            {
                printf("绑定CPU出错, ERROR:%s\n", strerror(errno));
                return -1;
            }
            coreId++;
            if (coreId > endCoreId)
            {
                coreId = startCoreId;
            }
        }
    }
    else if (mode == 2)
    {
        int core1 = atoi(argv[3]);
        int core2 = atoi(argv[4]);
        int coreId = core1;
        while (1)
        {
            CPU_ZERO(&mask);
            CPU_SET(coreId, &mask);
            // 进程迁移到CPU i
            if (sched_setaffinity(pid, sizeof(mask), &mask) == -1)
            {
                printf("绑定CPU出错, ERROR:%s\n", strerror(errno));
                return -1;
            }
            if (coreId == core1)
            {
                coreId = core2;
            }
            else
            {
                coreId = core1;
            }
        }
    }
    else if(mode ==3){
        int coreCount = argc - 3;
        for(i = 0;i<coreCount;i++){
            coreList[i] = atoi(argv[i+3]);
        }
        int coreIndex = 0;
        int coreId;
        while(1){
            coreId = coreList[coreIndex];
            CPU_ZERO(&mask);
            CPU_SET(coreId, &mask);
            // 进程迁移到CPU i
            if (sched_setaffinity(pid, sizeof(mask), &mask) == -1)
            {
                printf("绑定CPU出错, ERROR:%s\n", strerror(errno));
                return -1;
            }
            coreIndex++;
            if(coreIndex>coreCount){
                coreIndex = 0;
            }
        }
    }
    else
    {
        printf("mode can only be 1 or 2\n");
        return 1;
    }
    return 0;
}
